#include <string.h>
#include <iostream>
using std::cout;
using std::endl;

void * operator new(size_t sz){
    cout << "void * operator new(size_t)" << endl;
    return malloc(sz);
}
void operator delete(void* p){
    cout << "void operator delete(void*)" << endl;
    free(p);
}

class Student
{
public:
    Student(int id,int score,const char * name)
        : _id(id)
          , _score(score)
          , _name(new char[strlen(name) + 1]())
    {
        strcpy(_name,name);
        cout << "Student(int,int,const char *)" << endl;
    }

    Student(const Student & rhs)
        : _id(rhs._id)
          , _score(rhs._score)
          , _name(new char[strlen(rhs._name) + 1]())
    {
        strcpy(_name,rhs._name);
        cout << "Student(const Student&)" << endl;
    }

    Student& operator=(const Student & rhs){
        if(this != &rhs){
            delete [] _name;
            _name = new char[strlen(rhs._name) + 1]();
            strcpy(_name,rhs._name);
            _id = rhs._id;
            _score = rhs._score;
        }
        cout << "Student & operator=" << endl;
        return *this;
    }

    void * operator new(size_t sz){
        cout << "void * operator new(size_t)" << endl;
        return malloc(sz);
    }
    void operator delete(void* p){
        cout << "void operator delete(void*)" << endl;
        free(p);
    }

    /* void destroy(){ */
    /*     if(_name){ */
    /*         delete [] _name; */
    /*         _name = nullptr; */
    /*     } */
    /* } */
private:
    ~Student(){
        if(_name){
            delete [] _name;
            _name = nullptr;
        }
        cout << "~Student()" << endl;
    }

private:
    int _id;
    int _score;
    char * _name;
};

void test0(){
    Student * sp = new Student(1001,98,"Jack");
    /* delete sp; */
    /* sp = nullptr; */

    //Student stu(1002,97,"Tom");
}

void test1(){
    int * p = new int(1);
    delete p;
    p = nullptr;
}

int main(void){
    test0();
    return 0;
}
